/*
 * Projet Cryptolib CPS3 ASIP:
 *
 * Couche C pure des traitements spécifiques du programme d'exemple
 *
*/
#ifndef spec_controleur_h
#define spec_controleur_h

#include "sys_dep.h"

/* Actions */
#define ck_action_t CK_ACTION
#define CK_CONTINUE 0UL
#define CK_GOTO_FIN 1UL
#define CK_GOTO_SAISIE_CODE 2UL
#define CK_GOTO_REINIT_CONTEXTE 3UL

/* Choix utilisateur */
#define ANNULATION    -1
#define CONFIRMATION  1
#define N_TENTATIVES    2
#define TROIS_TENTATIVES    1
#define DEMANDE_RECYCLAGE    3

/* Code PKCS#11 personnalisés */
#define CKR_ERREUR_INATTENDUE 0x80000001
#define CKR_LIBRAIRIE_NON_CHARGEE 0x80000002
#define CKR_LISTE_FONCTIONS_INDISPONIBLE 0x80000003
#define CKR_LISTE_FONCTIONS_NON_INITIALISEE 0x80000004
#define CKR_AUCUN_LECTEUR_PRESENT 0x80000005
#define CKR_AUCUNE_CARTE_SUPPORTEE 0x80000006
#define CKR_UTILISATEUR_AUTHENTIFIE 0x80000007
#define CKR_UTILISATEUR_NON_AUTHENTIFIE 0x80000008
#define CKR_INTERRUPTION_UTILISATEUR 0x80000009
#define CKR_CODE_PORTEUR_INVALIDE 0x80000010
#define CKR_LONGUEUR_CODE_PORTEUR_INVALIDE 0x80000011
#define CKR_DEMANDE_RECYCLAGE 0x80000012
#define CKR_ECHEC_CONSTRUCTION_SLOTS_CARTE 0x80000013
#define CKR_CARTE_TROUVEE 0x80000014
#define CKR_CARTE_RECHERCHEE_INTROUVABLE 0x80000015
#define CKR_OPERATION_NON_CONFORME 0x80000016
#define CKR_OBJET_RECHERCHE_INTROUVABLE 0x80000017
#define CKR_OBJET_EXISTE_MAIS_NON_MODIFIABLE 0x80000018
#define CKR_AUCUN_OBJET_A_MODIFIER 0x80000019
#define CKR_MODE_SANS_CONTACT_UTILISATEUR_NON_AUTHENTIFIE 0x80000020
#define CKR_TRAITEMENT_NON_SUPPORTE_EN_MODE_SANS_CONTACT 0x80000021

/* Flags personnalisés */
#define CKF_AUCUN_CODE_PORTEUR_ERRONE 0x80000001
#define CKF_UN_OU_PLUSIEURS_CODES_PORTEUR_ERRONES 0x80000002
#define CKF_DERNIERE_TENTATIVE_CODE_PORTEUR_AVANT_BLOCAGE 0x80000003
#define CKF_CODE_PORTEUR_BLOQUE 0x80000004
#define CKF_TROIS_ESSAIS_RESTANTS 0x80000005
#define CKF_DEUX_ESSAIS_RESTANTS 0x80000006
#define CKF_UN_ESSAI_RESTANT 0x80000007
#define CKF_AUCUN_CODE_DEBLOCAGE_ERRONE 0x80000008
#define CKF_UN_OU_PLUSIEURS_CODES_DEBLOCAGE_ERRONES 0x80000009
#define CKF_DERNIERE_TENTATIVE_CODE_DEBLOCAGE_AVANT_BLOCAGE 0x80000010
#define CKF_CODE_DEBLOCAGE_BLOQUE 0x80000011
#define CKF_CODE_PORTEUR_CONFORME 0x80000012
#define CKF_LONGUEUR_CODE_PORTEUR_NON_CONFORME 0x80000013
#define CKF_CODE_PORTEUR_NON_CONFORME 0x80000014
#define CKF_CODE_PORTEUR_INCORRECT 0x80000015
#define CKF_CODE_DEBLOCAGE_CONFORME 0x80000016
#define CKF_LONGUEUR_CODE_DEBLOCAGE_NON_CONFORME 0x80000017
#define CKF_CODE_DEBLOCAGE_NON_CONFORME 0x80000018
#define CKF_CODE_DEBLOCAGE_INCORRECT 0x80000019
#define CKF_CODES_DIFFERENTS    0x80000020
#define CKF_N_ESSAIS_AVANT_BLOCAGE    0x80000021
#define CKF_TROIS_ESSAIS_AVANT_BLOCAGE    0x80000022
#define CKF_MODE_BLOQUE 0

/* Types de retrait */
#define TYPE_RETRAIT_CARTE 0
#define TYPE_RETRAIT_LECTEUR 1

/* Types d'actions sur carte ou lecteur */
#define TYPE_ACTION_INCONNUE 0
#define TYPE_ACTION_RETRAIT_CARTE 1
#define TYPE_ACTION_INSERTION_CARTE 2
#define TYPE_ACTION_RETRAIT_LECTEUR 3
#define TYPE_ACTION_CONNEXION_LECTEUR 4

typedef unsigned long ck_action_t;

/*
 * Association identifiantSlot/numeroSerieCarte
 */
typedef struct SLOT_CARTE {
	
	CK_SLOT_ID identifiantSlot;
	unsigned char numeroSerieCarte[16];

} SLOT_CARTE;

/*
 * Pointeur sur SLOT_CARTE
 */
typedef SLOT_CARTE PTR SLOT_CARTE_PTR;

/*
 * Table d'associations d'identifiantSlot/numeroSerieCarte
 */
typedef struct MAP_SLOTS_CARTES {

	SLOT_CARTE_PTR *pSlotsCartes;
	CK_ULONG taille;

} MAP_SLOTS_CARTES;

/*
 * Contexte de réalisation des appels spécifiques
 */
typedef struct CONTEXTE_TRAITEMENTS_SPECIFIQUES {

	CK_FUNCTION_LIST_PTR pFonctionsP11;
	CK_SLOT_ID identifiantSlot;
	CK_SESSION_HANDLE identifiantSession;
	CK_SESSION_INFO infosSession;
	CK_OBJECT_HANDLE identifiantObjet;
	CK_TOKEN_INFO infosCarte;
	CK_CHAR pNomApplication[32];
	MAP_SLOTS_CARTES mapSlotsCartes;

	/* Indique si une session est en lecture/ecriture (CK_TRUE => lecture/ecriture | CK_FALSE => lecture seule) */
	CK_BBOOL estSessionLectureEcriture;
	CK_BBOOL verifierConformiteCodeAvantAuthentification;
	CK_BBOOL mentionnerNbEssaisRestantsAvantAuthentification;

	/* Flag indiquant combien de saisies de code porteur erroné supporte la carte avant de se bloquer
	 * CKF_N_ESSAIS_AVANT_BLOCAGE
	 * ou CKF_TROIS_ESSAIS_AVANT_BLOCAGE
	 */
	CK_FLAGS flagNbEssaisPossiblesAvantBlocageCodePorteur;

	/* Flags permettant de déterminer le message à afficher concernant le nombre d'essai
	 * CKF_AUCUN_CODE_ERRONE
	 * ou CKF_UN_OU_PLUSIEURS_CODES_ERRONES
	 * ou CKF_DERNIERE_TENTATIVE_AVANT_BLOCAGE
	 * ou CKF_CARTE_BLOQUEE
	 * ou CKF_TROIS_ESSAIS_RESTANTS
	 * ou CKF_DEUX_ESSAIS_RESTANTS
	 * ou CKF_UN_ESSAI_RESTANT
	 */
	CK_FLAGS flagMessageEssaisRestantsAvantBlocageCodePorteur;
	CK_FLAGS flagMessageEssaisRestantsAvantBlocageCodeDeblocage;

	/* Flags permettant de déterminer le message à afficher concernant la conformité d'un code (porteur/déblocage)
	 * CKF_CODE_PORTEUR_CONFORME
	 * ou CKF_LONGUEUR_CODE_PORTEUR_NON_CONFORME
	 * ou CKF_CODE_PORTEUR_NON_CONFORME
	 * ou CKF_CODE_PORTEUR_INCORRECT
	 */
	CK_FLAGS flagMessageConformiteCodePorteur;
	CK_FLAGS flagMessageConformiteCodeDeblocage;

	/**********************/
	/* FONCTIONS CALLBACK */
	/**********************/
	int (*pDemandeConnexionLecteur)(void);
	int (*pDemandeInsertionCarte)(void);
	int (*pDemandeChoixNbEssaisPossiblesAvantBlocageCodePorteur)(void);
	int (*pDemandeSaisieCodePorteur)(CK_FLAGS, CK_FLAGS, char**, unsigned char[16]);
	int (*pDemandeRecyclageCodePorteur)(CK_FLAGS, CK_FLAGS, CK_FLAGS, char**, char**, char**, unsigned char[16]);
	int (*pDemandeActionLecteurCarte)(int, unsigned char[16]);
	void (*pDeclencheAlerteCarteRetrouvee)(void);
	int (*pDemandeModificationObjet)(CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR *, CK_ULONG_PTR);

} CONTEXTE_TRAITEMENTS_SPECIFIQUES;

/*
 * Pointeur sur le contexte de réalisation des appels spécifiques
 */
typedef CONTEXTE_TRAITEMENTS_SPECIFIQUES PTR CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR;



/*********************/
/* FONCTIONS ANNEXES */
/*********************/

/*
 * Réinitialise les identifiants (slot/session) et informations (carte/session) du contexte de réalisation des appels spécifiques
 */
void reinitialiseIdentifiantsEtInfosContexteTraitementsSpecifiques(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Scanne tous les slots et mémorise dans le contexte la première carte supportée rencontrée
 */
CK_RV recuperePremiereCarte(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Ouvre une session sur la carte mémorisée dans le contexte
 */
CK_RV ouvreSession(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Ouvre une session sur la première carte supportée rencontrée
 */
CK_RV ouvreSessionSurPremiereCarte(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Détermine si une authentification est nécessaire
 */
CK_BBOOL authentificationNecessaire(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, CK_RV*);

/* 
 * Mémorise dans le contexte, sur la base des informations carte, le nombre d'essais restants avant blocage
 */
CK_RV infoNbEssaisCode(unsigned long, CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Détermine le statut d'authentification de l'utilisateur
 */
CK_RV authentification(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Mémorise dans le contexte, sur la base des informations carte, la (non)conformité du code porteur
 */
CK_RV infoConformiteCode(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, char *);

/* 
 * Scanne tous les slots avec carte pour créer un instantané mémorisant les associations (identifiantSlot/numeroSerieCarte)
 */
CK_RV instantane(CK_FUNCTION_LIST_PTR, MAP_SLOTS_CARTES*);

/* 
 * Appelle C_Login et traite le code retour
 */
CK_ACTION login(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, CK_RV*, unsigned long, CK_UTF8CHAR_PTR);

/* 
 * Détermine le type d'action retrait Lecteur/Carte qui est survenu
 */
int identifieTypeActionRetrait(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, unsigned char*, int);

/* 
 * Scanne tous les slots avec carte pour trouver la carte avec le numéro de série spécifier en argument
 */
CK_RV chercheLecteurContenantCarte(CK_FUNCTION_LIST_PTR, unsigned char [16], CK_SLOT_ID *);

/*
 * Récupère l'identifiant d'un objet de données applicatives (jeton) 
 */
CK_RV recuperationIdentifiantObjetDonneesApplicatives(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* Lit l'attribut d'un objet de données applicatives (jeton) */
CK_RV litAttributValeurObjet(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, CK_ATTRIBUTE[], CK_ULONG*);




/****************************************/
/* FONCTIONS DE TRAITEMENTS SPECIFIQUES */
/****************************************/

/* 
 * Réalise le traitement spécifique d'état connexion carte
 */
CK_RV TS_etatConnexionCarte(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Réalise le traitement spécifique d'assistant authentification
 */
CK_RV TS_assistantAuthentification(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Réalise le traitement spécifique d'état de saisie du code porteur
 */
CK_RV TS_etatSaisieCodePorteur(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Réalise le traitement spécifique de recyclage du code porteur
 */
CK_RV TS_recyclageCodePorteur(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR);

/* 
 * Réalise le traitement spécifique d'authentification après retrait carte ou lecteur
 */
CK_RV TS_authentificationApresRetrait(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, int);

/* 
 * Réalise la lecture d'un objet de donnees applicatives (jeton)
 */
CK_RV TS_lectureObjetDonneesApplicatives(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, CK_ATTRIBUTE valeurAttributs[], CK_ULONG* tailleValeurAttributs);

/* 
 * Réalise la modification d'un objet de données applicatives (jeton)
 */
CK_RV TS_modificationObjetDonneesApplicatives(CONTEXTE_TRAITEMENTS_SPECIFIQUES_PTR, CK_ATTRIBUTE valeurAttributs[], CK_ULONG* tailleValeurAttributs);

#endif
